import { useAtomValue } from "jotai";
import { useEffect, useState } from "react";
import { useSearchParams } from "react-router";
import { Button, Form, Input, Select, Spin } from "antd";
import FullSizeModal from "@/components/FullSizeModal";
import type { IOrder, IProgram, IProgramStatus } from "@/lib/types";
import ProgramStatus from "@/components/ProgramList/ProgramStatus";
import ProgramSummary from "@/components/ProgramList/ProgramSummary";
import useFetch from "@/lib/hooks/useFetch";
import { addOrder, getOrderDetail, updateOrder } from "@/lib/api/order";
import { tokenAtom } from "@/store/user";
import { getDeviceList } from "@/lib/api/device";
import ProgramSelector from "./ProgramSelector";
import { useMessage } from "@/providers/AntdMessageProvider";
import getRequestErrorMessage from "@/lib/utils/getRequestErrorMessage";
import { getProgramInfo, getProgramStatus } from "@/lib/api/program";
import ProgramSelectModal from "@/components/ProgramSettingDialog/ProgramSelectModal";

type EditOrderDialogProps = {
  visible: boolean;
  target: IOrder | null; // edit target
  onClose: () => void;
  onSuccess: () => void;
};
export default function EditOrderDialog(props: EditOrderDialogProps) {
  const { visible, target, onClose, onSuccess } = props;
  const [, setSearch] = useSearchParams();
  const [programSelectModalVisible, setProgramSelectModalVisible] =
    useState(false);
  const [modelNumber, setModelNumber] = useState("");
  const [selection, setSelection] = useState<{
    program: IProgram | null;
    status: IProgramStatus[] | null;
  }>({
    program: null,
    status: null,
  });
  const [form] = Form.useForm();
  const token = useAtomValue(tokenAtom);
  const message = useMessage();

  const { isLoading: isDeviceListLoading, data: deviceList } = useFetch({
    fetchFn: (signal) =>
      getDeviceList({ pageNum: 1, pageSize: 999 }, token, signal).then(
        (res) => {
          if (res.code !== 200) {
            throw res;
          }
          return res.rows;
        },
      ),
    immediate: true,
  });

  const { isLoading: isDetailLoading, refetch: loadDetail } = useFetch({
    fetchFn: (orderId: number) =>
      getOrderDetail(orderId, token).then(async (res) => {
        if (res.code !== 200) {
          throw res;
        }
        const programDetail = await getProgramInfo(res.data.programId, token);
        if (programDetail.code !== 200) {
          throw programDetail;
        }
        return { order: res.data, program: programDetail.data };
      }),
    onError(error) {
      message.error(getRequestErrorMessage(error));
    },
    onSuccess({ order, program }) {
      const value = form.getFieldsValue();
      form.setFieldsValue({
        orderNo: order.orderNo,
        modelNo: order.modelNo,
        modelName: order.modelName,
        experimentItem: order.experimentItem,
        deviceId: order.deviceId,
        program: { ...value.program, program },
      });
      setModelNumber(order.modelName);
      setSelection((p) => ({
        ...p,
        program,
      }));
    },
  });

  const { refetch: loadProgramStatus } = useFetch({
    fetchFn: (programId: number) =>
      getProgramStatus(programId, token).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        return res.data;
      }),
    onError(error) {
      message.error(getRequestErrorMessage(error));
    },
    onSuccess(data) {
      const value = form.getFieldsValue();
      form.setFieldsValue({
        ...value,
        program: {
          ...value.program,
          status: data,
        },
      });
      setSelection((p) => ({ ...p, status: data }));
    },
  });

  const { isLoading: isAddLoading, refetch: _addOrder } = useFetch({
    fetchFn: (data: Parameters<typeof addOrder>[0]) =>
      addOrder(data, token).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        return res;
      }),
    onError(error) {
      message.error(getRequestErrorMessage(error));
    },
    onSuccess() {
      message.success("添加成功！");
      onSuccess();
      onClose();
    },
  });

  const { isLoading: isUpdateLoading, refetch: _updateOrder } = useFetch({
    fetchFn: (data: Parameters<typeof updateOrder>[0]) =>
      updateOrder(data, token).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        return res;
      }),
    onError(error) {
      message.error(getRequestErrorMessage(error));
    },
    onSuccess() {
      message.success("修改成功！");
      onSuccess();
      onClose();
    },
  });

  function handleSubmit(
    data: Parameters<typeof addOrder>[0] & {
      program: { program: IProgram; status: IProgramStatus };
    },
  ) {
    const {
      program: { program },
      ...rest
    } = data;
    console.log(data);
    if (target) {
      _updateOrder({
        ...rest,
        orderId: target.orderId,
        programId: program.programId,
      });
    } else {
      _addOrder({
        ...rest,
        programId: program.programId,
      });
    }
  }

  useEffect(() => {
    if (visible && target) {
      loadDetail(target.orderId);
      loadProgramStatus(target.programId);
    }
  }, [visible, target, loadDetail, loadProgramStatus]);

  return (
    <>
      <FullSizeModal
        visible={visible}
        onClose={onClose}
        onClosed={() => {
          form.resetFields();
          setSelection({ program: null, status: null });
        }}
        fullscreen
        title="订单"
      >
        <div className="flex h-full flex-col px-10">
          <Spin className="flex-none" spinning={isDetailLoading}>
            <Form
              layout="horizontal"
              className="flex items-center justify-center pb-8 pt-10"
              form={form}
              onFinish={handleSubmit}
            >
              <div className="grid grid-cols-3 gap-x-4">
                <Form.Item
                  label="委托单号"
                  name="orderNo"
                  rules={[{ required: true }]}
                >
                  <Input />
                </Form.Item>
                <Form.Item
                  label="型号"
                  name="modelNo"
                  rules={[{ required: true }]}
                >
                  <Input
                    onInput={(e) =>
                      setModelNumber((e.target as HTMLInputElement).value)
                    }
                  />
                </Form.Item>
                <Form.Item
                  label="名称"
                  name="modelName"
                  rules={[{ required: true }]}
                >
                  <Input />
                </Form.Item>
                <Form.Item
                  label="实验项目"
                  name="experimentItem"
                  rules={[{ required: true }]}
                >
                  <Input />
                </Form.Item>
                <Form.Item
                  label="设备"
                  name="deviceId"
                  rules={[{ required: true, message: "请选择设备" }]}
                >
                  <Select
                    loading={isDeviceListLoading}
                    options={deviceList?.map((device) => ({
                      label: device.deviceName,
                      value: device.deviceId,
                    }))}
                    showSearch
                    optionFilterProp="label"
                  />
                </Form.Item>
                <Form.Item
                  label="程序"
                  name="program"
                  rules={[{ required: true, message: "请选择程序" }]}
                >
                  <ProgramSelector
                    onOpen={(matchModel) => {
                      if (matchModel) {
                        setSearch((p) => {
                          p.set("pmn", modelNumber);
                          return p;
                        });
                      }
                      setProgramSelectModalVisible(true);
                    }}
                  />
                </Form.Item>
              </div>
              <Form.Item className="ml-8">
                <Button
                  htmlType="submit"
                  loading={isAddLoading || isUpdateLoading}
                >
                  保存
                </Button>
              </Form.Item>
            </Form>
          </Spin>
          <div className="min-h-0 flex-auto overflow-auto">
            <ProgramStatus data={selection.status || []} />
          </div>
          <div className="flex-none">
            <ProgramSummary
              program={selection.program}
              status={selection.status}
            />
          </div>
        </div>
      </FullSizeModal>
      <ProgramSelectModal
        visible={programSelectModalVisible}
        onClose={() => {
          setSearch((search) => {
            search.delete("pmn");
            return search;
          });
          setProgramSelectModalVisible(false);
        }}
        onConfirmSelection={(program, status) => {
          setSelection({ program, status });
          form.setFieldValue("program", { program, status });
          form.validateFields(["program"]);
        }}
      />
    </>
  );
}
